package bsts.model;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;

/*
 * Author Than Htet Aung : A007950R , Add comparable methods
 */
public class Account implements Serializable, Comparable<Account> {

	private static final long serialVersionUID = 1L;

	private String accountNo;
	private User regByUser;
	private AccountStatus accountStatus;
	private Date activated_Date;
	private Date deactivated_Date;
	private HashMap<Long, Subscription> subscriptions;

	public Account(String accountNo, User regByUser) {
		this.accountNo = accountNo;
		this.regByUser = regByUser;
		this.activated_Date = new Date();
		this.accountStatus = AccountStatus.Activated;
		subscriptions = new HashMap<Long, Subscription>();
	}

	public String getAccountNo() {
		return accountNo;
	}

	public void setAccountNo(String accountNo) {
		this.accountNo = accountNo;
	}

	public User getRegByUser() {
		return regByUser;
	}

	public void setRegByUser(User regByUser) {
		this.regByUser = regByUser;
	}

	public AccountStatus getAccountStatus() {
		return accountStatus;
	}

	public void setAccountStatus(AccountStatus accountStatus) {
		this.accountStatus = accountStatus;

		if (accountStatus.equals(AccountStatus.Deactivated)) {
			setDeactivated_Date(new Date());
			terminateSubscriptions();
		} else {
			setActivated_Date(new Date());
			setDeactivated_Date(null);
		}
	}

	public Date getActivated_Date() {
		return activated_Date;
	}

	public String getStrActivated_Date() {
		SimpleDateFormat sdfFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		return sdfFormat.format(activated_Date);
	}

	public void setActivated_Date(Date activated_Date) {
		this.activated_Date = activated_Date;
	}

	public Date getDeactivated_Date() {
		return deactivated_Date;
	}

	public Date getDeactivatedDate() {
		return deactivated_Date;
	}

	public String getStrDeactivated_Date() {
		SimpleDateFormat sdfFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		if (deactivated_Date == null)
			return "-";
		return sdfFormat.format(deactivated_Date);
	}

	public void setDeactivated_Date(Date deactivated_Date) {
		this.deactivated_Date = deactivated_Date;
	}

	public Collection<Subscription> getSubscriptionCollection() {
		return subscriptions.values();
	}
	
	public ArrayList<Subscription> getSubscriptions() {
		ArrayList<Subscription> arrSubscriptions = new ArrayList<Subscription>(subscriptions.values());
		Collections.sort(arrSubscriptions);
		return arrSubscriptions;
	}

	public void setSubscription(Subscription s) {
		this.subscriptions.put(s.getSubscriptionId(), s);
	}
	
	public void addSubscription(Subscription subscription) {
		subscriptions.put(subscription.getSubscriptionId(), subscription);
	}
	
	public void terminateSubscriptions() {
		ArrayList<Subscription> arrSubscriptions = new ArrayList<Subscription>(getSubscriptionCollection());
		for (Subscription subscription : arrSubscriptions) {
			if (subscription.getSubscriptionStatus().equals(SubscriptionStatus.Activated)) {
				subscription.setSubscriptionStatus(SubscriptionStatus.Terminated);
			}
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((accountNo == null) ? 0 : accountNo.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Account other = (Account) obj;
		if (accountNo == null) {
			if (other.accountNo != null)
				return false;
		} else if (!accountNo.equals(other.accountNo))
			return false;
		return true;
	}

	@Override
	public int compareTo(Account arg0) {
		// TODO Auto-generated method stub
		return getAccountNo().compareTo(arg0.getAccountNo());
	}

}
